package contegor.scire.structure;

import java.util.concurrent.ExecutorService;

import contegor.scire.core.Container;
import contegor.scire.core.IdFragment;
import contegor.scire.core.MissingElementException;
import contegor.scire.core.ReturnPoint;
import contegor.scire.core.Task;
import contegor.scire.core.Version;

/**
 * Transient and one thread {@link ConceptCloud} implementation.
 *
 * @version $Revision$
 * @author  Héctor Cirbián Pousa ($Author$)
 */
@Version("$Id$")
public class TransientAsynchronousConceptCloud extends AbstractConceptCloud {

  private class TaskRunner<T> implements Runnable {

    private Container container;
    private Task<T> task;
    private ReturnPoint<? super T> rp;

    public TaskRunner(Container container, Task<T> task, ReturnPoint<? super T> rp) {
      this.container = container;
      this.task      = task;
      this.rp        = rp;
    }

    public void run() {
        container.process(task, rp);
    } 
  }

  protected transient ExecutorService executor;

  public TransientAsynchronousConceptCloud(IdFragment rootId, ExecutorService executor) {
    super();
    this.root     = new CloudRootContainerImpl(System.currentTimeMillis(), null, rootId);
    this.executor = executor;
  }

  public <T> void process(Task<T> task, ReturnPoint<? super T> rp) {
    if (this.root.getId().sameRoot(task.getTargetContainerId())) {
      Container container = find(task.getTargetContainerId());
      if (container != null) {
        executor.execute(new TaskRunner<T>(container, task, rp));
        return;
      }
    }
    rp.manage(task.getTaskId(), new MissingElementException("Can't find target container: " + task.getTargetContainerId()));
    rp.finish(task.getTaskId());
  }

  /** Closes this instance and releases its resources.*/
  public void close() {
    this.executor.shutdown();
  }
}
